package com.app.shop.config;


import com.app.shop.util.DateUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * AOP用户访问日志记录,针对所有controller方法进行切面链拦截
 * 获取用户请求URL以及所有参数，进行访问日志存储，拦截地址先存储到内存然后存储到数据库，
 * 不适合高并发超量请求地址记录，如为高并行接口请写日志进行记录
 *
 * @author chenliwei
 */
@Aspect
@Component
public class WebLogAspect {

    private final static Log logger = LogFactory.getLog(WebLogAspect.class);

    ThreadLocal<Long> startTime = new ThreadLocal<Long>();

    ThreadLocal<String> resMsgLog = new ThreadLocal<String>();

    @Pointcut("execution(public * com.app.shop.controller..*.*(..))")
    public void webLog() {
    }

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        startTime.set(System.currentTimeMillis());

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //以下方法获取信息暂不使用如使用自行打开即可
        HttpServletResponse response = attributes.getResponse();
        String classType = joinPoint.getTarget().getClass().getName();
        Class<?> clazz = Class.forName(classType);
        //访问controller位置
        String clazzName = clazz.getName();
        //获取方法名称
        String methodName = joinPoint.getSignature().getName();
        //获取访问登录用户信息，如为登录方法获取验证码方法自动过滤
        StringBuffer path = request.getRequestURL();

        logger.info("访问时间-[" + DateUtil.getTime()+ "]|访问请求地址-[" + path + "]");
        logger.info("clazzName : " + clazzName);
        logger.info("methodName : " + methodName);
        logger.info("URL : " + request.getRequestURL().toString());
        logger.info("HTTP_METHOD : " + request.getMethod());
        logger.info("IP : " + request.getRemoteAddr());
        resMsgLog.set(path.toString());

    }

    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {

        // 处理完请求，重新打印各项处理日志
        logger.info(resMsgLog.get()+"|访问耗时：["+(System.currentTimeMillis() - startTime.get())+"毫秒]");

    }


}